//
// Created by QU on 2024/1/21.
//

// c++ standard library
#include <cassert>
#include <iostream>
#include <list>
#include <vector>
#include <map>
#include <set>

// boost library
#include <boost/pool/pool.hpp>
#include <boost/pool/object_pool.hpp>
#include <boost/pool/singleton_pool.hpp>

// using namespace
using std::cin, std::cout, std::endl;
using std::string;
using boost::pool;
using boost::object_pool;
using boost::singleton_pool;

// pool包含4个组成部分: 最简单的pool;  分配类实例的object_pool; 单间内存池singleton_pool; 可用于标准库的pool_alloc. (只介绍前3个)

// 仅仅用于标记的空类
struct pool_tag{};
typedef boost::singleton_pool<pool_tag, sizeof(double)> sp1;   // 内存池的定义

int main(int argc, char const *argv[]) {
    // singleton_pool与pool的接口2完全一致, 可以用它分配简单数据类型(POD)内存指针, 但是, 它是一个单件.
    // 是对pool内存池的封装，在其基础上加了锁，避免多线程操作的安全问题(默认使用的是boost.thread)，并暴露了常用的接口。

    // singleton_pool主要有两个模板参数(其他的可以使用默认值),
    // 第一个参数Tag可以仅仅用于标记不同的单件, 可以是空类, 甚至可以只进行声明, (此形式还被用于boost.exception
    // 第二个参数RequestedSize等同于pool构造函数中的整数requested_size, 可以指示pool分配的内存块的大小.

    // singleton_pool的接口和pool的完全一样, 但是其singleton_pool中的成员函数均是静态的, 所以不需要声明
    // singleton_pool的实例, 直接使用::全局变量操作符调用静态成员函数即可, 因为 singleton_pool是单件, 所以他的生命周期和整个程序的周期一样长
    // 除非手动调用release_memory()或者purge_memory(), 否则不会自动释放所占用的内存.

    // 除了上面的两点, singleton_pool和pool完全相同.

    // 用法
    // 这里注意使用的全局的变量的::操作符.
    int *p  = (int *)sp1::malloc();
    assert(sp1::is_from(p));
    cout << "object_pool request_size is: " << sp1::requested_size << endl;

    void * ret = nullptr;
    for (int i = 0; i < 100; ++i) {
        ret = sp1::ordered_malloc();
        if (!ret){
            cout  << "pool Memory malloc error." << endl;
            break;
        }
    }

    sp1::release_memory();

}